#include "obmp_type.h"
#include "obmp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define DEBUG(fmt,...)    printf("%d@[%s]%d: " fmt, getppid(), __func__, __LINE__,  ##__VA_ARGS__)
#define malloc(s)	  obmp_malloc(s)

extern void obmp_print_cache_state(void);

void *malloc_thread(void *arg)
{
    void *p, *q;
    mem_unit_t *unit_info = NULL;

    p = malloc(4); /* min */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);

    q = malloc(4); /* min */
    unit_info = ptr_to_mem_unit(q);
    DEBUG("q:%p belong:%d\n", q, unit_info->info.belongs);
    free(p);
    free(q);

    p = malloc(4); /* min */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);

    q = malloc(4); /* min */
    unit_info = ptr_to_mem_unit(q);
    DEBUG("q:%p belong:%d\n", q, unit_info->info.belongs);
    free(p);
    free(q);

    p = malloc(508); /* middle */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);
    p = malloc(512); /* middle */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);

    p = malloc(513); /* middle */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);
    p = malloc(520); /* middle */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);

    p = malloc(1023); /* middle */
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);

    p = malloc(1028);
    unit_info = ptr_to_mem_unit(p);
    memset(p, 0, 1024);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);

    p = malloc(4096);
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);

    p = malloc(8192);
    unit_info = ptr_to_mem_unit(p);
    DEBUG("p:%p belong:%d\n", p, unit_info->info.belongs);
    free(p);

    for (int i = 0; i < 100000; i++) {
            p = malloc(i%1024);
            free(p);
    }

    return NULL;
}

int main()
{
    int i = 0;
    const int thread_count = 1;
    pthread_t thread[thread_count];
    struct timeval now, before;

    printf("Input anykey to start test...\n");
    getchar();
    printf("Test start...\n");

    gettimeofday(&before, NULL);
    for (i = 0; i < thread_count; i++) {
        pthread_create(&thread[i], NULL, malloc_thread, NULL);
    }

    for (i = 0; i < thread_count; i++) {
        pthread_join(thread[i], NULL);
    }
    gettimeofday(&now, NULL);

    printf("used %ld ms\n", (now.tv_sec - before.tv_sec) * 1000 + (now.tv_usec - before.tv_usec) / 1000);
    obmp_print_cache_state();

    getchar();

    return 0;
}
